The write system call is one of the most basic routines provided by the kernel. It writes data, in bytes as specified by the caller, from a buffer declared by the user in the program and then writes it into the file supplied by the calling process. In most modern operating systems, a program that needs to write data to a file stored in a filesystem uses the Write system call. The file is identified by the file descriptor that is obtained from a previous call to open.
Write, thus, takes three arguments:
Contents |
The write system call interface[1][2][3] is standardized by the POSIX specification. Data is written to a file by calling the write function. The function prototype is :
size_t write(int fd, const void *buf, size_t nbytes);
Argument | Description |
---|---|
fd
|
It is the file descriptor which has been obtained from the call to open. It is an integer value. The values 0, 1, 2 can also be given, for standard input, standard output & standard error, respectively . |
buf
|
It points to a character array, which can be used to store content obtained from the file pointed to by fd. |
nbytes
|
It specifies the number of bytes to be written from the file into the character array. |
In above syntax, size_t
is a typedef
. It is unsigned data type defined in stddef.h
. sizeof
operator produces an integer value which is of this type.[4]
The write function returns the number of bytes successfully written into the array, which may at times be less than the specified nbytes. It returns -1 if EOF is encountered.
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> int main (int argc, char *argv[]) { int fd1; char buf[128]; fd1 = open(argv[1], O_WRONLY); if (fd1 == -1) { perror("File cannot be opened"); return EXIT_FAILURE; } /* Enter the data to be written into the file */ scanf("%127s", buf); write(fd1, buf, strlen(buf)); /* fd1 is the file descriptor, buf is the character array used to hold the data, strlen(buf) informs the function that the number of bytes equal to the length of the string in the buffer need to be copied */ return 0; }
Listed below are some errors[5][6] that could be encountered during writing to a file. The errors are macros listed in errno.h .
Error Numbers | Error | Meaning |
---|---|---|
4
|
EINTR
|
The system call was interrupted. |
5
|
EIO
|
Low-level errors, often concerned with hardware read/write operations. |
9
|
EBADF
|
The file descriptor fd is not valid, or an attempt is being made to write into a file opened in 'read-only' mode. |
13
|
EACCES
|
The user does not have the necessary permissions to write into the file. |
14
|
EFAULT
|
The address specified in the function is an invalid address. |
22
|
EINVAL
|
The argument(s) passed with the function is(are) invalid. |
27
|
EFBIG
|
The file size specified in nbytes is too large, and is greater than that allowed by the system. |
28
|
ENOSPC
|
No space available for writing onto the disc. |
32
|
EPIPE
|
The pipe is either broken, or the file at the other end of the pipe is not open for I/O purposes (most processes giving this type of error also generate the SIGPIPE signal). |
The write system call is not an ordinary function, in spite of the close resemblance . In Linux, the system call uses the operating code INT 80H of the assembly language, in order to transfer control over to the kernel[7]. The write system call, and its counterpart read, being low level functions, are only capable of understanding bytes. Write cannot be used to write records, like classes. Thus, higher level input-output functions (like printf) are required. Often, the high-level interface is preferred, as compared to the cluttered low-level interface. These functions call other functions internally, and these in turn can make calls to write, giving rise to a layered assembly of functions[8][9].
With the use of this assembly the higher level functions can collect bytes of data and then write the required data into a file.